package apt

import (
	"fmt"
	"os"

	"gitee.com/liumou_site/gf"
	"gitee.com/liumou_site/logger"
)

// UpdateIndex 更新 APT 包索引，执行 "apt update" 命令并记录相关日志信息。
// 参数:
//
//	无
//
// 返回值:
//
//	res: 表示更新操作是否成功，true 表示成功，false 表示失败。
func (api *AptStruct) UpdateIndex() (res bool) {
	// 继承屏蔽设置，将当前对象的 Ignore 和 BlackHole 属性传递给 Sudo 对象
	api.Sudo.Ignore = api.Ignore
	api.Sudo.BlackHole = api.BlackHole

	// 如果启用了调试模式，记录更新操作的日志信息
	if api.Debug {
		logger.Info("Apt Index Update")
	}

	// 定义需要执行的命令为 "apt update"
	cmd := "apt update"

	// 使用 Sudo 权限执行命令
	api.Sudo.RunSudo(cmd)

	// 根据命令执行结果记录相应的日志信息
	if api.Sudo.Err == nil && api.Info {
		logger.Info("Apt Index Update Succeeded")
	} else {
		logger.Error("Apt Index Update Failed: ")
	}

	// 将执行过程中遇到的错误赋值给当前对象的 Err 属性
	api.Err = api.Sudo.Err

	// 根据是否有错误发生，返回相应的结果
	return api.Sudo.Err == nil
}

// Upgrade 执行系统升级操作，并返回升级是否成功的标志。
// 参数:
//
//	无
//
// 返回值:
//
//	res bool - 表示系统升级是否成功，true 表示成功，false 表示失败。
func (api *AptStruct) Upgrade() (res bool) {
	// 继承屏蔽设置，忽略某些特定的更新
	api.Sudo.Ignore = api.Ignore

	// 继承屏蔽设置，将某些更新视为已安装
	api.Sudo.BlackHole = api.BlackHole

	// 记录系统更新日志
	logger.Info("System Update")

	// 执行升级命令
	api.Sudo.RunSudo("apt dist-upgrade")

	// 根据执行结果输出相应的日志
	if api.Sudo.Err == nil && api.Info {
		// 如果没有错误且信息输出标志为真，则记录成功日志
		logger.Info("System Upgrade Successfully")
	} else {
		// 如果有错误，则记录失败日志
		logger.Error("System Upgrade  Failed")
	}

	// 将可能发生的错误赋值给 api.Err
	api.Err = api.Sudo.Err

	// 返回升级是否成功的标志
	return api.Sudo.Err == nil
}

// DownLoadPackage 下载指定名称的APT包到目标目录。
// 参数:
//
//	name - 要下载的APT包的名称。
//	dir  - 目标目录路径，用于存放下载的APT包。
//
// 返回值:
//
//	无直接返回值，但通过api.Err记录错误信息。
//
// 功能描述:
//
//	该函数首先检查目标目录是否存在，如果不存在则尝试创建。
//	然后切换到目标目录并执行APT下载命令，最后恢复到原始工作目录。
//	如果在任何步骤中发生错误，错误信息会被记录到api.Err中，并通过日志输出。
func (api *AptStruct) DownLoadPackage(name, dir string) {
	api.Err = nil

	// 获取当前工作目录，以便后续恢复。
	curDir, _ := os.Getwd()

	// 检查目标目录是否存在，如果不存在则创建目录。
	d := gf.NewFile(dir)
	d.Exists()
	d.IsDir()
	if !d.ExIst {
		d.Mkdir(dir, 0755)
		if d.Err != nil {
			api.Err = d.Err
			logger.Error("Create Directory Failed: ", d.Err)
			return
		}
	}

	// 再次确认目标路径是否为目录，确保操作的安全性。
	d.IsDir()
	if !d.IsDirs {
		api.Err = fmt.Errorf("this is not a directory: %s", dir)
		logger.Error("This is not a directory: ", dir)
		return
	}

	// 切换到目标目录，准备执行下载操作。
	api.Err = os.Chdir(dir)
	if api.Err != nil {
		return
	}

	// 执行APT下载命令，下载指定名称的APT包。
	cmd := fmt.Sprintf("apt download %s", name)
	api.Sudo.RunSudo(cmd)
	if api.Sudo.Err != nil {
		api.Err = api.Sudo.Err
		logger.Error("Download Package Failed: ", api.Sudo.Err)
		return
	}

	// 恢复到原始工作目录，确保环境一致性。
	_ = os.Chdir(curDir)
}

// DownLoadPackageList 下载指定名称的包列表到目标目录。
// 参数:
//
//	name []string - 包名称的字符串切片，表示需要下载的包名称列表。
//	dir string    - 目标目录路径，所有包将被下载到该目录中。
//
// 返回值:
//
//	无返回值。
func (api *AptStruct) DownLoadPackageList(name []string, dir string) {
	// 遍历包名称列表，逐个下载
	for _, v := range name {
		api.DownLoadPackage(v, dir)
	}
}
